﻿#include "CDevDataBase.h"
#include "CLogOper.h"
#include "CPointMgrBase.h"
CDevDataBase::CDevDataBase()
{
	m_pMutex = new QMutex(QMutex::Recursive);
	m_dDetecOffset = 0;
	m_pDevDataCam = new CDevDataCam();
	m_sRobotIp = "";
	m_sRobotPort = "";
	m_bSuddenStop = false;
	m_bPlcConnectState = false;
	m_nPolItemNum = 0;                            //1->0
	m_dRobRunSpeed = 0;                           //机器人主机运行速度(默认行走速度)
	m_dRobRunSpeedZ = 0;                          //机器人主机运行速度Z
	m_nDeviceEnum = 0;                            //设备类型，设备类型 1001主机  2001 A型号相机  3001 温度传感器  3002 气体传感器
	m_nRobType = 0;                               //机器人类型  1-A型号 2-B型号  101科右中版本
	m_dSafeDistance = 0;                          //Z轴安全位置
	m_nRobWorkType = 0;                           //机器人工作模式  0 手动模式 1 自动任务模式
	m_dCorse = 0;                                 //机器人运行总里程数
	m_nProximitySensorOffset = 0;                 //接近传感器偏移量
	m_nNo2LabelOffset = 0;                        //#2标签偏移量
	m_nIsOpenAutoCharge = 0;                      //是否开启低电量自动充电
	m_nAutoChargeThreshold = 0;                   //低电量自动充电阈值
	m_dReturnSpeed = 0;                           //返程速度
	m_dFrontObstacleAvoidance = 0;                //避障开关
	m_dBackObstanceAvidance = 0;                  //跨皮带保护开关
	m_dChargeCutOffThreshold = 0;                 //充电截止阈值
	m_dChargeCutOffVolTage = 0;                   //充电截止电压
	m_dHoldingAddPowerThreshold = 0;              //待机补电阈值
	m_dHoldingAddPowerVoltage = 0;                //待机补电电压
	m_dTaskEleQuantityThreshold = 0;              //执行任务电量阈值
	m_dTaskEleQuantityVoltage = 0;                //执行任务电量电压
	m_dForceChargeThreshold = 0;                  //强制充电阈值
	m_dForceChargeVoltage = 0;                    //强制充电电压
	m_dChargeFallLoopCount = 0;                   //充电失败循环次数
	m_dChargeCommunicationDelay = 0;              //充电通讯延时
	m_dChargeAutoRetornDistance = 0;              //充电自动退回距离
	m_dLevelOneSpeedCut = 0;                      //一级减速
	m_dLevelTwoSpeedCut = 0;                      //二级减速
	m_dDriveMotorUpperCurrent = 0;                //驱动电机电流上限
	m_dDriveMotorCurrentSleep = 0;                //驱动电机电流延时
	m_dDriveMotorUpperTorque = 0;                 //驱动电机扭矩上限
	m_dDriveMotorTorqueSleep = 0;                 //驱动电机扭矩延时
	m_dDriveMotorUpperTemp = 0;                   //驱动电机温度上限
	m_dDriveMotorTempSleep = 0;                   //驱动电机温度延时
	m_dLiftMotorUpperCurrent = 0;                 //升降电机电流上限
	m_dLiftMotorCurrentSleep = 0;                 //升降电机电流延时
	m_dLiftMotorUpperTorque = 0;                  //升降电机扭矩上限
	m_dLiftMotorTorqueSleep = 0;                  //升降电机扭矩延时
	m_dLiftMotorUpperTemp = 0;                    //升降电机温度上限
	m_dLiftMotorTempSleep = 0;                    //升降电机温度延时
	m_dLiftMotorSleepSet = 0;                     //升降电机速度值设定
	m_dOneClickBaceLocation = 0;                  //一键返航位置(mm)
	m_dAutoSwitchOpenBatteryThre = 0;		      //自动分闸电量阈值(%)
	m_dAutoSwitchOpenVolThre = 0;			      //自动分闸电压阈值(V)
	m_dIsAutoFlush = 0;						      //巡检结束是否冲洗
	m_nIsHaveFlush = 0;
	m_nFlushBlong = 0;
	m_nFlushRFID1 = 0;						      //冲洗位置前RFID号
	m_nFlushRFID2 = 0;                            //冲洗位置后RFID号
	m_nVoiceAverigeTime = 0;					  //取噪声平均值时间间隔(s)
	m_nVoiceOffset = 0;						      //声音传感器偏移值(db)
	m_nTempOffset = 0;						      //温度传感器偏移值
	m_nHumOffset = 0;						      //湿度传感器偏移值
	m_nGasOffset = 0;						      //可燃气体传感器偏移值
	m_nPM25Offset = 0;						      //PM2.5传感器偏移值
	m_nPM10Offset = 0;						      //PM10传感器偏移值
	m_nCoOffset = 0;							  //Co传感器偏移值
	m_nHumEnable = 0;							  //湿度传感器是否生效
	m_pDevDataCam = new CDevDataCam();		      //云台子设备数据类


	m_nAlarmStopTime = 0;                         //报警停留时间
	m_nCollectTime = 0;                           //云台巡检项采集时间
	m_nChargeYTPreset = 0;                        //云台充电预置点
	m_sRobObstacleCfg="";
	m_nBelogn = 0;
	m_nLabelMode = 0;                             //标签模式(开/关)

	m_nSave = 0;
	m_nDirectionSelect = 0;
	m_nParameterdDistribut = 0;
	m_bTaskExec = false;
	m_bBeltAWork = false;                         //A侧皮带运行状态    
	m_bBeltBWork = false;                         //B侧皮带运行状态
	m_nRobRunMode = 0;

	m_mapRollerConfig.clear();
	m_nRollerNum = 0;                             //当前托辊号(计算后刷新)
	m_nCamerRollerNum = 0;
	m_nBelogn = 0;
}

CDevDataBase::~CDevDataBase()
{
}

bool CDevDataBase::lock(int nMs)
{
	return m_pMutex->tryLock(nMs);
}

void CDevDataBase::unLock()
{
	m_pMutex->unlock();
}

bool CDevDataBase::getDevCtr(QString sGuid)
{
	if (m_sCtrGuid== sGuid)
	{
		return true;
	}
	if (m_sCtrGuid == "")
	{
		m_sCtrGuid=sGuid;
		return true;
	}
	else
	{
		return false;
	}
}

bool CDevDataBase::releaseDevCtr(QString sGuid)
{
	if (m_sCtrGuid == sGuid)
	{
		m_sCtrGuid = "";
	}
	return true;
}

void CDevDataBase::addDevExecLog(SDevExecLog sSDevExecLog)
{
	/*if (m_mapLogId.contains(sSDevExecLog.m_sDescriptionl))
	{
		return;
	}*/
	SExecLog sLog;
	sLog.m_nAlarmLevel = sSDevExecLog.m_nAlarmLevel;
	sLog.m_sDescriptionl = sSDevExecLog.m_sDescriptionl;
	sLog.m_sDevName = m_sRobName;
	sLog.m_sFuncName = sSDevExecLog.m_sDevName;
	if (sLog.m_sDescriptionl == "")
	{
		sLog.m_sDescriptionl = "/";
	}
	CLogOper::instance().addMsg(sLog);
	//m_mapLogId.insert(sLog.m_sDescriptionl, sLog.m_sDescriptionl);
}


QString CDevDataBase::getCtrCmdExecReInfo(int nType)
{
	QString sStr = A2T("其他");
	switch (nType)
	{
	case enSuccess:
	{
		sStr = A2T("执行成功");
	}
	break;
	case enSetCmdFail:
	{
		sStr = A2T("设置命令失败");
	}
	break;
	case enResetCtrCmdFail:
	{
		sStr = A2T("复位执行命令失败");
	}
	break;
	case enResetCtrCmdReFail:
	{
		sStr = A2T("复位执行命令反馈失败");
	}
	break;
	case enResetResultFail:
	{
		sStr = A2T("复位执行结果失败");
	}
	break;
	case enWriteParamFail:
	{
		sStr = A2T("写参数失败");
	}
	break;
	case enReadFail:
	{
		sStr = A2T("读取数据失败");
	}
	break;
	case enPlcNoFeedBack:
	{
		sStr = A2T("PLC无反馈");
	}
	break;
	case enInterruptCmd:
	{
		sStr = A2T("控制命令被打断");
	}
	break;
	case enCtrCmeExecOn:
	{
		sStr = A2T("控制命令执行中");
	}
	break;
	case enCtrCmeExecFail:
	{
		sStr = A2T("PLC执行控制命令失败");
	}
	break;
	case enExecTimeout:
	{
		sStr = A2T("控制命令执行超时");
	}
	break;
	case enOther:
	{
		sStr = A2T("其他异常");
	}
	break;
	default:
		sStr = A2T("其他异常");
		break;
	}

	return sStr;
}

QString CDevDataBase::getCurrRollerName()
{
	QString sRollerName = "";
	if (m_pPointMgrBase->getPoint().size() > 11)
	{
		sRollerName = m_pPointMgrBase->getPoint()[11]->getName();
	}
	if (sRollerName != "")
	{
		m_sRollerDesc = sRollerName;
	}
	return m_sRollerDesc;
}

int CDevDataBase::getCurrRollerNo(QString& sRollerDesc)
{
	int nRollerNo = -1;
	QString sRollerName = "";
	if (m_pPointMgrBase->getPoint().size() > 11)
	{
		nRollerNo = m_pPointMgrBase->getPoint()[11]->getValue().toInt();
		sRollerName = m_pPointMgrBase->getPoint()[12]->getValue().toString();
	}
	if (nRollerNo != -1)
	{
		m_nRollerNum = nRollerNo;
		m_sRollerDesc = sRollerName;
		sRollerDesc = sRollerName;
	}
	return m_nRollerNum;
}

int CDevDataBase::getRollerNoEx(double dPos, QString & sRollerDesc, int nBelong)
{
	QMutexLocker loker(&m_MutexRollerCfg);//智能锁	
	int nRollerNum = findRoller(dPos, nBelong);
	if (nRollerNum == -1)
	{
		nRollerNum = m_nRollerNum;
	}
	else
	{
		m_nRollerNum = nRollerNum;
	}
	if (m_mapRollerConfig.contains(dPos))
	{
		SRollerNo sRollerNo = m_mapRollerConfig.value(dPos);
		if (nBelong == 0)
		{
			sRollerDesc = sRollerNo.m_sRollerDescA;
		}
		else
		{
			sRollerDesc = sRollerNo.m_sRollerDescB;
		}
		m_sRollerDesc = sRollerDesc;
	}
	else
	{
		sRollerDesc = m_sRollerDesc;
	}
	return nRollerNum;
}

int CDevDataBase::getRollerNo(double dPos, QString & sRollerDesc, int nBelong)
{
	QMutexLocker loker(&m_MutexRollerCfg);//智能锁
	int nRollerNum = findRoller(dPos, nBelong);
	if (nRollerNum == -1)
	{
		nRollerNum = m_nCamerRollerNum;
	}
	else
	{
		m_nCamerRollerNum = nRollerNum;
	}
	if (m_mapRollerConfig.contains(dPos))
	{
		SRollerNo sRollerNo = m_mapRollerConfig.value(dPos);
		if (nBelong == 0)
		{
			sRollerDesc = sRollerNo.m_sRollerDescA;
		}
		else
		{
			sRollerDesc = sRollerNo.m_sRollerDescB;
		}
		m_sCamerRollerDesc = sRollerDesc;
	}
	else
	{
		sRollerDesc = m_sCamerRollerDesc;

	}
	return nRollerNum;
}

double CDevDataBase::findNearestKey(double dValue)
{
	if (m_mapRollerConfig.isEmpty())
	{
		return 0;
	}

	// 获取大于或等于value的最小键
	auto it = m_mapRollerConfig.lowerBound(dValue);

	// 边界情况处理：当value比所有键都大或都小时
	if (it == m_mapRollerConfig.end())
	{
		// value大于所有键
		--it;
		return it.key();
	}
	else if (it == m_mapRollerConfig.begin())
	{
		// value小于所有键
		return it.key();
	}

	// 获取大于或等于value的最小键
	double dUpperKey = it.key();
	// 获取小于value的最大键
	--it;
	double dLowerKey = it.key();

	// 比较哪个键更接近value
	if (std::abs(dUpperKey - dValue) < std::abs(dLowerKey - dValue))
	{
		return dUpperKey;
	}
	else
	{
		return dLowerKey;
	}
}

int CDevDataBase::findRoller(double & dValue, int nBelong)
{
	int nRollNum = -1;
	QVector<SRollerInfo>vecRollerInfo;
	for (QMap<double, SRollerNo>::iterator i = m_mapRollerConfig.begin(); i != m_mapRollerConfig.end(); i++)
	{
		if (nBelong == 0)
		{
			if (i.value().m_nRollerNoA >= 0)
			{
				SRollerInfo sRollerInfo;
				sRollerInfo.dLoaction = i.key();
				sRollerInfo.nRollerNum = i.value().m_nRollerNoA;
				vecRollerInfo.push_back(sRollerInfo);
			}
		}
		else
		{
			if (i.value().m_nRollerNoB >= 0)
			{
				SRollerInfo sRollerInfo;
				sRollerInfo.dLoaction = i.key();
				sRollerInfo.nRollerNum = i.value().m_nRollerNoB;
				vecRollerInfo.push_back(sRollerInfo);
			}
		}

	}
	double dLastVal = -1;
	double dNextVal = 9999;
	for (int i = 0; i < vecRollerInfo.size(); i++)
	{
		if (dValue >= vecRollerInfo[i].dLoaction)
		{
			dLastVal = vecRollerInfo[i].dLoaction;
		}
		else
		{
			dNextVal = vecRollerInfo[i].dLoaction;
		}
	}
	if ((dValue - dLastVal) < (dNextVal - dValue))
	{
		if (abs(dValue - dLastVal) < ROLLERINTER)
		{
			dValue = dLastVal;
		}
		else
		{
			dValue = -1;
		}
	}
	else
	{
		if (abs(dValue - dNextVal) < ROLLERINTER)
		{
			dValue = dNextVal;
		}
		else
		{
			dValue = -1;
		}
	}
	if (!m_mapRollerConfig.contains(dValue))
	{
		return -1;
	}
	else
	{
		SRollerNo sRollerNo = m_mapRollerConfig.value(dValue);
		if (nBelong == 0)//A侧
		{
			return sRollerNo.m_nRollerNoA;
		}
		else//B侧
		{
			return sRollerNo.m_nRollerNoB;
		}
	}
}
